import sys
import threading
import tkinter as tk
import webbrowser
import os
from tkinter import messagebox, filedialog
from PyPDF2 import PdfMerger

def get_pdf_files(directory):
    """递归遍历目录及其子目录，获取所有PDF文件的路径列表"""
    pdf_files = []
    for dirpath, _, filenames in os.walk(directory):
        for filename in filenames:
            if filename.endswith('.pdf'):
                pdf_files.append(os.path.join(dirpath, filename))
    return pdf_files

def merge_pdfs(pdf_files, output_path):
    """合并PDF文件并保存到指定路径"""
    merger = PdfMerger()
    for pdf in pdf_files:
        merger.append(pdf)
    with open(output_path, 'wb') as output_file:
        merger.write(output_file)

def check_output_path(output_path):
    """检查输出文件路径是否存在冲突"""
    if os.path.exists(output_path):
        show_result_window(output_path, True)
        return False
    else:
        return True



def select_directory(entry_var):
    """打开文件选择对话框让用户选择目录"""
    directory = filedialog.askdirectory()
    if directory:
        entry_var.set(directory)
        return directory

def merge_pdfs_callback(entry_var):
    """合并PDF文件的回调函数"""
    if not entry_var.get():
        messagebox.showwarning("警告", "请先选择一个目录！")
        return
    directory = entry_var.get()
    if directory:
        try:
            directory_name = os.path.basename(os.path.normpath(directory))
            output_filename = f"{directory_name}_merged.pdf"
            output_path = os.path.join(directory, output_filename)
            valid = check_output_path(output_path)
            if not valid:
                return
            pdf_files = get_pdf_files(directory)
            if not pdf_files:
                raise ValueError(f"在目录 {directory} 中没有找到任何PDF文件")

            # 使用线程来避免阻塞GUI
            def merge_thread():
                try:
                    merge_pdfs(pdf_files, output_path)
                    root.after(0, lambda: show_result_window(output_path))
                except Exception as e:
                    root.after(0, lambda: messagebox.showerror("错误", f"合并PDF时发生错误：{e}"))

            thread = threading.Thread(target=merge_thread)
            thread.start()
        except Exception as e:
            messagebox.showerror("错误", f"处理目录时发生错误：{e}")
    else:
        messagebox.showwarning("警告", "请先选择一个目录！")


def open_in_explorer(output_path):
    directory = os.path.dirname(output_path)  # 获取文件所在的目录
    if os.name == 'nt':  # Windows
        # 使用subprocess调用explorer来打开目录
        os.startfile(directory)
    elif os.name == 'posix':  # macOS or Linux
        if sys.platform == "darwin":  # macOS
            os.system(f'open "{directory}"')
        else:  # Linux
            try:
                # 使用xdg-open打开目录（这通常需要桌面环境）
                os.system(f'xdg-open "{directory}"')
            except Exception as e:
                # 使用Tkinter的messagebox显示警告
                messagebox.showwarning("警告", f"无法在Linux中打开目录：{e}")

def open_in_browser(output_path):
    try:
        webbrowser.open_new_tab(f"file:///{os.path.abspath(output_path).replace('\\', '/')}")
    except Exception as e:
        messagebox.showwarning("警告", f"无法在浏览器中打开文件：{e}")

def show_result_window(output_path, is_exit = False):
    """显示合并结果的窗口"""
    result_window = tk.Toplevel(root)
    result_window.title("合并结果")
    if is_exit:
        text = f"PDF文件已存在：\n{output_path}"
    else:
        text = f"PDF文件已成功合并并保存在：\n{output_path}"
    label = tk.Label(result_window, text=text)
    label.pack(pady=10)

    explorer_button = tk.Button(result_window, text="在资源管理器中打开", command=lambda: open_in_explorer(output_path))
    explorer_button.pack(side='left', padx=10, pady=10)

    browser_button = tk.Button(result_window, text="在浏览器中打开", command=lambda : open_in_browser(output_path))
    browser_button.pack(side='right', padx=10, pady=10)

def main():
    global root
    root = tk.Tk()
    root.title("PDF合并工具")
    # 禁止用户修改窗口尺寸
    root.resizable(width=False, height=False)

    frame = tk.Frame(root)
    frame.pack(pady=10)

    entry_var = tk.StringVar()
    entry = tk.Entry(frame, width=40, state='readonly', textvariable=entry_var)
    entry.pack(side=tk.LEFT, padx=5, pady=5, fill=tk.X, expand=True)

    browse_button = tk.Button(frame, text="浏览...", command=lambda: select_directory(entry_var))
    browse_button.pack(side=tk.RIGHT, padx=5, pady=5)

    clear_button = tk.Button(frame, text="清空", command=lambda: entry_var.set(""))
    clear_button.pack(side=tk.RIGHT, padx=5, pady=5)

    # 添加退出按钮
    exit_button = tk.Button(root, text="退出", command=root.quit)
    exit_button.pack(side=tk.BOTTOM, pady=5)

    button_frame = tk.Frame(root)
    button_frame.pack(pady=5)

    merge_button = tk.Button(button_frame, text="合并目录下所有PDF", command=lambda: merge_pdfs_callback(entry_var))
    merge_button.pack(padx=5, pady=5, fill=tk.X, expand=True)

    root.mainloop()

if __name__ == "__main__":
    main()